package com.qd.pay.thread;

import com.cdqidi.constant.ConstantDto;
import com.cdqidi.util.ExceptionUtil;
import com.qd.pay.domain.OrderReportNotifyDTO;
import com.qd.pay.domain.OrderReportNotifyErrorDTO;
import com.qd.pay.model.OrderReportNotifyError;
import com.qd.pay.model.OrderReportNotifyLog;
import com.qd.pay.repository.OrderReportNotifyErrorRepository;
import com.qd.pay.repository.OrderReportNotifyLogRepository;
import com.qd.pay.repository.OrderReportNotifyRepository;
import com.qd.pay.task.HttpNotify;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @program: pay
 * @description:
 * @author: sjk
 * @create: 2019/10/11
 */
@Service
@Slf4j
public class OrderNotifyService {
    private final HttpNotify httpNotify;
    private final OrderReportNotifyRepository orderReportNotifyRepository;
    private final OrderReportNotifyErrorRepository orderReportNotifyErrorRepository;
    private final OrderReportNotifyLogRepository orderReportNotifyLogRepository;
    private final OrderNotifyThread orderNotifyThread;
    private final OrderNotifyErrorThread orderNotifyErrorThread;


    public OrderNotifyService(HttpNotify httpNotify, OrderReportNotifyRepository orderReportNotifyRepository, OrderReportNotifyErrorRepository orderReportNotifyErrorRepository, OrderReportNotifyLogRepository orderReportNotifyLogRepository, @Lazy OrderNotifyThread orderNotifyThread, @Lazy OrderNotifyErrorThread orderNotifyErrorThread) {
        this.httpNotify = httpNotify;
        this.orderReportNotifyRepository = orderReportNotifyRepository;
        this.orderReportNotifyErrorRepository = orderReportNotifyErrorRepository;
        this.orderReportNotifyLogRepository = orderReportNotifyLogRepository;
        this.orderNotifyThread = orderNotifyThread;
        this.orderNotifyErrorThread = orderNotifyErrorThread;
    }

    @Transactional(rollbackFor = Exception.class)
    public void notifyAndSave(List<OrderReportNotifyDTO> list) {
        OrderReportNotifyLog notifyLog;
        OrderReportNotifyError orderReportNotifyError;
        String notifyUrl;
        String notifyBody;
        String sf = ConstantDto.SF1;
        for (OrderReportNotifyDTO orderReportNotifyDto : list) {
            notifyUrl = orderReportNotifyDto.getNotifyUrl();
            notifyBody = orderReportNotifyDto.getNotifyBody();
            notifyLog = new OrderReportNotifyLog();
            notifyLog.setNotifyTime(LocalDateTime.now());
            notifyLog.setNotifyUrl(notifyUrl);
            notifyLog.setNotifyBody(notifyBody);
            notifyLog.setOrderId(orderReportNotifyDto.getOrderId());
            try {
                httpNotify.sendHttp(notifyUrl, notifyBody);
            } catch (Exception e) {
                sf = ConstantDto.SF0;
                notifyLog.setErrMsg(ExceptionUtil.getExceptionMsg(e));
            }
            notifyLog.setSfcg(sf);
            notifyLog.setLogTime(LocalDateTime.now());
            try {
                orderReportNotifyLogRepository.save(notifyLog);
                notifyLog.freeData();
                if (sf.equals(ConstantDto.SF0)) {
                    orderReportNotifyError = new OrderReportNotifyError();
                    orderReportNotifyError.setErrCount(1);
                    orderReportNotifyError.setNotifyBody(orderReportNotifyDto.getNotifyBody());
                    orderReportNotifyError.setNotifyUrl(orderReportNotifyDto.getNotifyUrl());
                    orderReportNotifyError.setOrderId(orderReportNotifyDto.getOrderId());
                    orderReportNotifyError.setOutTradeNo(orderReportNotifyDto.getOutTradeNo());
                    orderReportNotifyError.setThirdPartyOrder(orderReportNotifyDto.getThirdPartyOrder());
                    orderReportNotifyError.setAddTime(LocalDateTime.now());
                    orderReportNotifyErrorRepository.save(orderReportNotifyError);
                    orderReportNotifyError.freeData();
                }
                orderReportNotifyRepository.removeById(orderReportNotifyDto.getNid());
                orderReportNotifyDto.freeData();
            } catch (Exception e) {
                orderNotifyThread.removeSet(orderReportNotifyDto.getNid());
                throw e;
            }
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void notifyErrorAndSave(List<OrderReportNotifyErrorDTO> rList) {
        String sf = ConstantDto.SF1;
        String notifyUrl;
        String notifyBody;
        OrderReportNotifyLog notifyLog;
        OrderReportNotifyError orderReportNotifyError;
        for (OrderReportNotifyErrorDTO orderReportNotifyErrorDto : rList) {
            notifyLog = new OrderReportNotifyLog();
            notifyLog.setNotifyTime(LocalDateTime.now());
            notifyLog.setOrderId(orderReportNotifyErrorDto.getOrderId());
            notifyUrl = orderReportNotifyErrorDto.getNotifyUrl();
            notifyBody = orderReportNotifyErrorDto.getNotifyBody();
            try {
                httpNotify.sendHttp(notifyUrl, notifyBody);
            } catch (Exception e) {
                sf = ConstantDto.SF0;
                notifyLog.setErrMsg(ExceptionUtil.getExceptionMsg(e));
                orderNotifyErrorThread.removeSet(orderReportNotifyErrorDto.getEid());
            }
            notifyLog.setNotifyUrl(notifyUrl);
            notifyLog.setNotifyBody(notifyBody);
            notifyLog.setSfcg(sf);
            notifyLog.setLogTime(LocalDateTime.now());
            try {
                orderReportNotifyLogRepository.save(notifyLog);
                notifyLog.freeData();

                if (sf.equals(ConstantDto.SF1)) {
                    orderReportNotifyErrorRepository.removeById(orderReportNotifyErrorDto.getEid());
                } else {
                    orderReportNotifyError = new OrderReportNotifyError();
                    orderReportNotifyError.setEid(orderReportNotifyErrorDto.getEid());
                    orderReportNotifyError.setErrCount(orderReportNotifyErrorDto.getErrCount() + 1);
                    orderReportNotifyError.setAddTime(LocalDateTime.now());
                    orderReportNotifyErrorRepository.updateById(orderReportNotifyError);
                    orderReportNotifyError.freeData();
                }
                orderReportNotifyErrorDto.freeData();
            } catch (Exception e) {
                orderNotifyErrorThread.removeSet(orderReportNotifyErrorDto.getEid());
                throw e;
            }

        }
    }
}
